#include <iostream>
#include <fstream>

#include "contacts.pb.h"

#define CONTACTS_FILE "./contacts.bin"

void addPeople(contacts2::PeopleInfo *people)
{
    //请求用户输入联系人信息
    std::cout << "----------联系人信息----------" << std::endl;
    std::cout << "请输入联系人姓名: ";
    std::string name;
    getline(std::cin, name);
    people->set_name(name);

    std::cout << "请输入联系人年龄: ";
    int age;
    std::cin >> age;
    //清除输入缓冲区内容，有三种结束方式：
    //1. 清除了256个字符
    //2. 清除了第一个\n
    std::cin.ignore(256, '\n');
    people->set_age(age);

    //输入电话
    for(int i = 0; ; ++i)
    {
        //电话号码
        std::string phone;
        std::cout << "请输入联系人电话(仅输入回车表示结束): ";
        getline(std::cin, phone);
        if(phone.empty())
            break;//仅输入回车
        contacts2::PeopleInfo_Phone *people_phone = people->add_phone();
        people_phone->set_phone(phone);
        //电话类型
        std::cout << "请输入电话类型(1. 移动电话 2. 固定电话): ";
        int type = 0;
        std::cin >> type;
        std::cin.ignore(256, '\n');
        //判断电话类型
        switch(type)
        {
            case 1:
                people_phone->set_type(contacts2::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_MP);
                break;
            case 2:
                people_phone->set_type(contacts2::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_TEL);
                break;
            default:
                std::cout << "输入有误！" << std::endl;
                break;
        }
    }
    //家庭地址
    contacts2::Address address;
    std::cout << "请输入家庭地址：";
    std::string host_address;
    getline(std::cin, host_address);
    if(!host_address.empty())
        address.set_host_address(host_address);

    std::cout << "请输入单位地址：";
    std::string unit_address;
    getline(std::cin, unit_address);
    if(!unit_address.empty())
        address.set_unit_address(unit_address);
    //使用泛型Any接收
    google::protobuf::Any *data = people->mutable_data();
    data->PackFrom(address);
    //其他联系方式
    std::cout << "请选择其他联系方式(1.QQ  2.wechat): ";
    int other_contact;
    std::cin >> other_contact;
    std::cin.ignore(256, '\n');
    if(other_contact == 1)
    {
        std::cout << "请输入QQ号:";
        std::string qq;
        getline(std::cin, qq);
        people->set_qq(qq);
    } 
    else if(other_contact == 2)
    {
        std::cout << "请输入微信号: ";
        std::string wechat;
        getline(std::cin, wechat);
        people->set_wechat(wechat);
    }
    else
        std::cout << "输入有误，无其他联系方式" << std::endl;
    //备注信息
    for(int i = 0; ;++i)
    {
        std::cout << "请输入第" << i + 1 << "备注信息标题(仅回车表示结束): ";
        std::string remark_info;
        getline(std::cin, remark_info);
        if(remark_info.empty())
            break;
        std::cout << "请输入备注信息内容: ";
        std::string remark_message;
        getline(std::cin, remark_message);

        people->mutable_remark()->insert({remark_info, remark_message});
    }

    std::cout << "-----------添加成功-----------" << std::endl;
}

int main()
{
    //打开通讯录文件，没有就创建
    //并将文件内容反序列
    contacts2::Contacts contacts;
    std::ifstream input(CONTACTS_FILE, std::ios::in | std::ios::binary);
    if(!input)//原先没有目标文件
        std::cout << "not found file, create a new file" << std::endl;
    else
    {
        //将通讯录文件内容反序列化到通讯录对象中
        if(!contacts.ParseFromIstream(&input))
        {
            std::cerr << "通讯录文件反序列化失败" << std::endl;
            input.close();//记得关闭文件
            return -1;
        }
    }

    //添加一个联系人
    addPeople(contacts.add_peoples());

    //将通讯录序列化，并写入文件
    //覆盖写
    std::ofstream out(CONTACTS_FILE, std::ios::out | std::ios::trunc | std::ios::binary);
    if(!contacts.SerializePartialToOstream(&out))
    {
        std::cerr << "通讯录序列化失败" << std::endl;
        input.close();//记得关闭文件
        out.close();
        return -1;
    }
    //到此序列化成功
    std::cout << "序列化成功" << std::endl;
    input.close();
    out.close();
}